package game.games.chartest;

import game.gfx.AbstractImageGeneratingGame;
import game.gfx.GraphicUtil;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;

public class CharTest extends AbstractImageGeneratingGame
{
    public enum GlyphSet
    {
        // other stuff
        SpacingModifierLetters            (0x002B0,0x002FF),
        CombiningDiacriticalMarks         (0x00300,0x0036F),
        GeneralPunctuation                (0x02000,0x0206F),
        SuperscriptsAndSubscripts         (0x02070,0x0209F),
        CurrencySymbols                   (0x020A0,0x020CF),
        CombiningMarks4Symbols            (0x020D0,0x020FF),
        LetterlikeSymbols                 (0x02100,0x0214F),
        NumberForms                       (0x02150,0x0218F),
        Arrows                            (0x02190,0x021FF),
        MathematicalOperators             (0x02200,0x022FF),
        MiscellaneousTechnical            (0x02300,0x023FF),
        BoxDrawing                        (0x02500,0x0257F),
        BlockElements                     (0x02580,0x0259F),
        GeometricShapes                   (0x025A0,0x025FF),
        MiscellaneousSymbols              (0x02600,0x026FF),
        // chars
        BasicLatin                        (0x00000,0x0007F),
        Latin1Supplement                  (0x00080,0x000FF),
        LatinExtendedA                    (0x00100,0x0017F),
        LatinExtendedB                    (0x00180,0x0024F),
        LatinExtendedAdditional           (0x01E00,0x01EFF),
        IPAExtensions                     (0x00250,0x002AF),
        Greek                             (0x00370,0x003FF),
        GreekExtended                     (0x01F00,0x01FFF),
        Cyrillic                          (0x00400,0x004FF),
        Hebrew                            (0x00590,0x005FF),
        Arabic                            (0x00600,0x006FF),
        ArabicPresentationFormsA          (0x0FB50,0x0FDFF),
        ArabicPresentationFormsB          (0x0FE70,0x0FEFF),
        // not supported
        ControlPictures                   (0x02400,0x0243F),
        EnclosedAlphanumerics             (0x02460,0x024FF),
        Dingbats                          (0x02700,0x027BF),
        Armenian                          (0x00530,0x0058F),
        Syriac                            (0x00700,0x0074F),
        Thaana                            (0x00780,0x007BF),
        Devanagari                        (0x00900,0x0097F),
        Bengali                           (0x00980,0x009FF),
        Gurmukhi                          (0x00A00,0x00A7F),
        Gujarati                          (0x00A80,0x00AFF),
        Oriya                             (0x00B00,0x00B7F),
        Tamil                             (0x00B80,0x00BFF),
        Malayalam                         (0x00D00,0x00D7F),
        Sinhala                           (0x00D80,0x00DFF),
        Thai                              (0x00E00,0x00E7F),
        Georgian                          (0x010A0,0x010FF),
        Ethiopic                          (0x01200,0x0137F),
        Cherokee                          (0x013A0,0x013FF),
        Runic                             (0x016A0,0x016F0),
        Hanunoo                           (0x01720,0x01173),
        TaiLe                             (0x01950,0x01974),
        Buginese                          (0x01A00,0x01A1F),
        
        
        Braille                           (0x02800,0x028FF),
        Glagolitic                        (0x02C00,0x02C5F),
        Coptic                            (0x02C80,0x02CFF),
        Gothic                            (0x10330,0x1034F),
        Ugaritic                          (0x10380,0x1039F),
        OldPersian                        (0x103A0,0x103D5),
        Phoenecian                        (0x10900,0x1091F),
        ByzantineMusicalSymbols           (0x1D000,0x1D0FF),
        WesternMusicalSymbols             (0x1D100,0x1D1FF),
        MathematicalAlphanumericSymbols   (0x1D400,0x1D7FF),
        Mahjong                           (0x1F000,0x1F02F),
        Domino                            (0x1F030,0x1F09F);
        
        private int first;
        private int last;
        
        private GlyphSet(int first, int last)
        {
            this.first = first;
            this.last = last;
        }
        
        public int getFirst()
        {
            return first;
        }
        
        public int getLast()
        {
            return last;
        }
    }

    @Override
    protected IMAGE_POSITION getImagePosition()
    {
        return IMAGE_POSITION.TOP_LEFT;
    }
    
    private Dimension imageSize;
    
    private int fontSize = 20;
    private Font font = new Font("Courier New", Font.TRUETYPE_FONT, fontSize);
    private StringBuilder sb = new StringBuilder();
    private BufferedImage image;
    
    @Override
    protected void onStart()
    {
        int nextLine = 0;
        
        String longestLine = "";
        int lines = 0;
        
        final int CHARS_PER_LINE = 5;
        
        
        for (GlyphSet g : GlyphSet.values())
        {
            this.sb.append(g.name() + "(" + Integer.toHexString(g.getFirst()) + "-" + g.getLast() + ")" + ":\n");
            lines++;
            
            StringBuilder sb = new StringBuilder();
            
            for (int i = g.getFirst(); i <= g.getLast(); i++)
            {
                if (font.canDisplay(i) && Character.isIdentifierIgnorable(i) == false && Character.isWhitespace(i) == false)
                {
                    if (sb.length() == 0)
                    {
                        sb.append(' ');
                    }
                    char[] cp = Character.toChars(i);
                    if (cp.length != 1)
                    {
                        System.out.println(cp);
                    }
                    for (char c : cp)
                    {
                        boolean isRightToLeft = Character.getDirectionality(i) == Character.DIRECTIONALITY_RIGHT_TO_LEFT
                                || Character.getDirectionality(i) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
                                || Character.getDirectionality(i) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
                                || Character.getDirectionality(i) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE;
                        if (isRightToLeft)
                        {
                            sb.append('\u202A');
                        }
                        sb.append(c);
                    }
                    sb.append(' ').append('\\').append('u');
                    String hexString = Integer.toHexString(i).toUpperCase();
                    for (int c = 0; c < 4 - hexString.length(); c++)
                    {
                        sb.append('0');
                    }
                    sb.append(hexString).append(' ');
                    if (nextLine > CHARS_PER_LINE)
                    {
                        this.sb.append(sb).append('\n');
                        nextLine = 0;
                        if (longestLine.length() < sb.length())
                        {
                            longestLine = sb.toString();
                        }
                        sb = new StringBuilder();
                        lines++;
                    }
                    else
                    {
                        nextLine++;
                    }
                }
            }
            this.sb.append(sb).append('\n');
            if (longestLine.length() < sb.length())
            {
                longestLine = sb.toString();
            }
            sb = new StringBuilder();
            lines++;
            this.sb.append('\n');
            lines++;
        }
        
        // image
        BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        // schwarze schrift
        g.setFont(font);
        FontMetrics fm = g.getFontMetrics();
        
        imageSize = new Dimension(fm.stringWidth(longestLine),  fm.getHeight() * lines);
        setPanelSize(imageSize);
    }
    
    @Override
    protected Dimension getImageSize()
    {
        return this.imageSize;
    }
    
    @Override
    protected BufferedImage getImage()
    {
        if (image == null)
        {
            // image
            BufferedImage image = new BufferedImage(imageSize.width, imageSize.height, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = image.createGraphics();
            // Weißer Hintergrund
            GraphicUtil.fillRect(g, new Point(0, 0), new Dimension(imageSize.width, imageSize.height), Color.WHITE);
            // schwarze schrift
            g.setColor(Color.BLACK);
            g.setFont(font);
            FontMetrics fm = g.getFontMetrics();
            int index = 0;
            int line = 1;
            while (index < sb.length())
            {
                // find next \n
                int nextIndex = index;
                char c;
                boolean nlFound = false;
                do
                {
                    c = sb.charAt(nextIndex);
                    if (c == '\n')
                    {
                        nlFound = true;
                    }
                    else
                    {
                        nextIndex++;
                    }
                }
                while (nlFound == false);
                String output = sb.substring(index, nextIndex);
                g.drawString(output, 0, line * (fm.getHeight() - 1));
                index = nextIndex + 1;
                line++;
            }
            this.image = image;
        }
        return image;
    }
    
    @Override
    protected void initConfig()
    {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    protected void doNext()
    {
        // TODO Auto-generated method stub
        
    }
    
    public static void main(String[] args)
    {
        Thread t = new Thread(new CharTest(), "CharTest");
        t.start();
    }
    
}
